package com.strato.repository.monitor.v1_0_0.listener;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.jar.JarFile;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

import com.strato.base.osgi.v1_0_0.BundleUtil;
import com.strato.logging.v1_0_0.api.Log;
import com.strato.logging.v1_0_0.api.LogFactory;
import com.strato.repository.monitor.v1_0_0.FileListener;

public class RedeployListener implements FileListener {

	private Log log=LogFactory.getLog(getClass());
	
	private BundleContext context;

	public RedeployListener(BundleContext context){
		this.context=context;
	}
	
	@Override
	public void onStart(File monitoredfile) {
	}

	@Override
	public void onStop(File notMonitoredFile) {
	}

	@Override
	public void onAdd(String path, InputStream is) {
		try {
			context.installBundle(getPathUrl(path), is);
			log.info("   Installed bundle "+path);
		} catch (BundleException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onChange(String path, InputStream is) {
		Bundle bundle = context.getBundle(getPathUrl(path));
		if(bundle!=null){
			try {
				bundle.uninstall();
			} catch (BundleException e) {
				e.printStackTrace();
			}
		}
		try {
			waitForFileReady(path);
			Bundle newbundle = context.installBundle(getPathUrl(path), is);
			BundleUtil.startBundle(newbundle);
		} catch (BundleException e) {
			e.printStackTrace();
		}
		log.info("RE-installed bundle "+path);
	}

	private void waitForFileReady(String path) {
		for(int i=0;i<3;i++){
			File file=new File(path);
			JarFile jarFile=null;
			try {
				jarFile=new JarFile(file);
				jarFile.entries();
				return;
			} catch (IOException e) {
				e.printStackTrace();
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}finally{
				if(jarFile!=null){
					try {
						jarFile.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	private String getPathUrl(String path){
		return "file:/"+path;
	}
	
	@Override
	public void onDelete(String path) {
		Bundle bundle = context.getBundle(getPathUrl(path));
		if(bundle!=null){
			try {
					bundle.uninstall();
					System.out.println("UN-installed bundle "+path);
			} catch (BundleException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void onIntervalStart() {
	}

	@Override
	public void onIntervalEnd(Map<String, String> eventsToFile) {
	}

}
